#!/bin/bash

# Settings
PATCHES_DIR="${PWD}/main/patches"
ICONSETS_DIR="${PWD}/main/iconsets"
GIT_DIR="${PWD}/git"
WORK_DIR="${PWD}/psi"
PATCH_LOG="${PWD}/long.log"
SHORT_LOG="${PWD}/short.log"
SKIP_BAD_PATCHES="${SKIP_BAD_PATCHES:-0}"
BACKUP_POSTFIX=`date "+%F_%H%M%S"`

# Init
edit_mode=0
term_width=`tput cols`

die() { echo " !!!ERROR: ${1}"; exit 1; }

prepare_dir() {
  [ -z "${1}" ] && die "dir must not be empty";
  if [ ! -e "${1}" ]; then
    mkdir "${1}"
  else
    echo -en "${1} dir already exists. [b]ackup, [\033[4mr\033[0m]emove, [o]verwrite: "
    read -n 1 act
    case $act in
      b) echo "backuping..."; mv "${1}" "${1}.${BACKUP_POSTFIX}"; mkdir "${1}"  ;;
      o) echo "leave for overwriting" ;;
      ""|r) echo " removing..."; rm -rf "${1}"; mkdir "${1}" ;;
      *) die "unsupported option" ;;
    esac
    
  fi
  [ ! -d "${1}" ] && die "can't prepare dir ${1}"
}

unpack_git() {
  git clone "${GIT_DIR}" "${1}"
  cd "${1}"
  git submodule init
  git config --list --local | grep submodule | cut -f 2 -d . | sort -u | while read -r sm; do
    git config --local --remove-section submodule.$sm
    git config --add submodule.$sm.url "${GIT_DIR}/${sm}"
  done
  git submodule update
}

commit_tree()
{
  echo "configure*" >> .gitignore
  git rm configure*
  "${QCONF}"
  git submodule foreach 'git add .; [ -n "`git status |grep "nothing to commit"`" ] || git commit -am "${@}"'
  git add .; [ -n "`git status |grep "nothing to commit"`" ] || git commit -am "${@}";
}


while [ -n "$1" ]; do
  case $1 in
    -e) edit_mode=1; ;;
    *) configure_opts="${configure_opts} $1"; ;;
  esac
  shift
done

qconfs="qt-qconf qconf-qt4 qconf"
for qc in $qconfs; do QCONF="`which ${qc} 2>/dev/null`"; [ -n "$QCONF" ] && break; done
[ -z "$QCONF" ] && die "neither of ${qconfs} is found"

[ -f "${PATCH_LOG}" ] && rm "${PATCH_LOG}"
[ -f "${SHORT_LOG}" ] && rm "${SHORT_LOG}"


PATCHES=`(cd "${PATCHES_DIR}"; ls -1 *diff) 2>/dev/null`
[ -z "${PATCHES}" ] && die "patches not found in ${PATCHES_DIR}"
[ -d "${GIT_DIR}/.git" ] || die "${GIT_DIR} is not git repo"



ZENITY_LIST=`echo "${PATCHES}" | sed 's/.*/FALSE \0/'`
UP_TO=`zenity --title 'Patch selector' --text 'Apply patches up to?' \
	--list --radiolist --column '' --column Patch --height 440 \
	--width 600 ${ZENITY_LIST}`
[ "$?" != 0 ] && die "aborted"

prepare_dir "${WORK_DIR}"

echo "patches will be applied up to ${UP_TO}"

unpack_git "${WORK_DIR}"
cp -a "${ICONSETS_DIR}/system/default" "${WORK_DIR}/iconsets/system"
#cp -a "${ICONSETS_DIR}/roster/default" "${WORK_DIR}/iconsets/roster"
touch "${SHORT_LOG}"

if [ ! -z "${UP_TO}" ]
then
  cd "${WORK_DIR}"
  for p in $PATCHES; do
     [ "${p}" = "${UP_TO}" ] && [ "$edit_mode" = 1 ] && commit_tree "before ${p}"
     git apply -p1 "${PATCHES_DIR}/${p}" || {
       broken=1
       echo -n "Patch ${p} can't be applied cleanly. "
       answer="n"
       [ -e "../mkpatch" ] && {
         echo -n "try to fix it? [Y/n] "
         sleep 2s
         read answer
       } || {
         echo "unfortunatelly mkpatch util is not found. can't fix automatically"
       }
       if [ -z "$answer" -o "$answer" = "y" -o "$answer" = "Y" ]; then
         echo "Fixing patch $p"
         commit_tree "before try to fix ${p}"
         git apply -p1 -C1 "${PATCHES_DIR}/${p}" && {
           broken=0
           git submodule foreach 'git add -A'
           git add -A
           ../mkpatch > "${PATCHES_DIR}/${p}"
         }
         [ "$broken" =  1 ] && die "Fuzz for ${p} is to big. try to fix manually"
       fi
       if [ "$broken" = 1 ]; then
         commit_tree "before broken patch ${p}"
         die "Failed to apply ${p}";
       fi
     }
     [ "${p}" = "${UP_TO}" ] && [ "$edit_mode" = 0 ] && commit_tree "upto ${p}"
     [ "${p}" = "${UP_TO}" ] && break;
  done
fi
# add all to make git diff --cached working
git submodule foreach 'git add -A'
git add -A


( cd "${WORK_DIR}"; "$QCONF"; )

[ "${UP_TO%%-*}" -ge 8000 ] && configure_opts="${configure_opts} --enable-plugins"
( cd "${WORK_DIR}"; ./configure --disable-growl --debug --prefix=/usr --no-separate-debug-info --qtdir=/usr $configure_opts )

for proj in psi.pro.user*; do cp "$proj" "${WORK_DIR}" 2>/dev/null; done

